package top.lishuoboy.knife4j.swagger3_0_0.advice;

import lombok.extern.slf4j.Slf4j;
import org.springframework.validation.FieldError;
import org.springframework.validation.ObjectError;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;
import top.lishuoboy.knife4j.swagger3_0_0.enums.Code;
import top.lishuoboy.knife4j.swagger3_0_0.exception.MyApiException;
import top.lishuoboy.knife4j.swagger3_0_0.vo.RespVo;

import java.util.ArrayList;
import java.util.List;

@Slf4j
@RestControllerAdvice
public class MyExceptionControllerAdvice {
    /* 参数校验异常 MethodArgumentNotValidException */
    @ExceptionHandler({MethodArgumentNotValidException.class})
    public RespVo MethodArgumentNotValidExceptionHandler(MethodArgumentNotValidException e) {
        log.warn("参数未校验异常", e);
        // 从异常对象中拿到ObjectError对象
        List<String> objErrList = new ArrayList<>();
        List<ObjectError> objectErrors = e.getBindingResult().getAllErrors();
        for (int i = 0; i < objectErrors.size(); i++) {
            ObjectError objError = objectErrors.get(i);
            if (objError instanceof FieldError) {
                FieldError fieldErr = (FieldError) objError;
                objErrList.add("(" + (i + 1) + ")" + fieldErr.getField() + "=" + fieldErr.getRejectedValue() + "，（" + fieldErr.getDefaultMessage() + "）");
            } else {
                log.warn("不属于FieldError，可考虑优化。{}", objError.getClass());
                objErrList.add("(" + (i + 1) + ")" + objError.getObjectName() + "（" + objError.getDefaultMessage() + "）");
            }
        }
        return RespVo.builder().code(Code.FAIL_CLIENT.code).msg(objErrList.toString()).build();
    }

    /* 自定义API异常 */
    @ExceptionHandler({MyApiException.class})
    public RespVo myApiExceptionHandler(MyApiException e) {
        log.warn("自定义API异常", e);
        return RespVo.builder().code(e.getCode()).msg(e.getMsg()).build();
    }

    /* 所有异常 */
    @ExceptionHandler({Exception.class})
    public RespVo exceptionHandler(Exception e) {
        log.warn("异常", e);
        int code;
        if (e instanceof IllegalArgumentException) {
            code = Code.FAIL_CLIENT.code;
        } else {
            code = Code.FAIL_SERVER.code;
        }
        return RespVo.builder().code(code).msg(e.getMessage()).build();
    }
}
